package com.example.demo.service;


import com.example.demo.bean.*;
import com.example.demo.mapper.*;

import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;

import static java.sql.Types.NULL;


@Service
public class MessageService {
    @Resource
    private MessageMapper messageMapper;
    @Resource
    private PoiMapper poiMapper;
    @Resource
    private Car_MessageMapper car_messageMapper;
    @Resource
    private CarMapper carMapper;
    @Resource
    private DistanceMapper distanceMapper;
    @Resource
    private Get_CarMapper get_carMapper;
    @Resource
    private GoodsMapper goodsMapper;
    @Resource
    private OwnersMapper ownersMapper;
    @Resource
    private Message_OwnerMapper messageOwnerMapper;
    @Resource
    private Goods_messageMapper goods_messageMapper;
    @Resource
    private RecordMapper recordMapper;
    @Resource
    private SimpMessagingTemplate messagingTemplate;

    Random random = new Random();

    public void sendMessage(Map<String,Object> message){
        messagingTemplate.convertAndSend("/topic/messages",message);
        System.out.println("向前端发送了消息");
    }

    public void sendMessage(List<?> message){
        messagingTemplate.convertAndSend("/topic/messages",message);
        System.out.println("向前端发送了消息");
    }

    public void produceAndExport(){
        poiMapper.produce();
        poiMapper.translate();
        poiMapper.sale();
//        Map<String,Object> produceAndExport_message = new HashMap<>();
//        produceAndExport_message.put("routeOrNot",0);
//        produceAndExport_message.put("message","生产和销售中");
//        sendMessage(produceAndExport_message);
    }

    public void generateMessage(){
        Message message = new Message();
        Records records = new Records();
        LocalDateTime currentTime = LocalDateTime.now();
        records.setRecord_time(Timestamp.valueOf(currentTime));
        recordMapper.insertRecord(records);
        List<Poi> last_factory = poiMapper.search_last_factory();
        List<Integer> last_factory_id = new ArrayList<>();
        if(last_factory.size() > 15) {
            for (int i = 0; i < 15; i++) {
                int index = random.nextInt(last_factory.size());
                message.setDestination(last_factory.get(index).getPoi_id());
                last_factory_id.add(last_factory.get(index).getPoi_id());
                message.setIndustry_id(last_factory.get(index).getIndustry_id());
                message.setGoods_weight(0.2*last_factory.get(index).getMax_stock()/last_factory.get(index).getTransformation_rate());
                message.setRecord_id(records.getRecord_id());
                messageMapper.addMessage(message);
                last_factory.remove(index);
            }
        }
        else {
            for(Poi last_f : last_factory){
                message.setDestination(last_f.getPoi_id());
                last_factory_id.add(last_f.getPoi_id());
                message.setIndustry_id(last_f.getIndustry_id());
                message.setGoods_weight(0.2*last_f.getMax_stock()/last_f.getTransformation_rate());
                message.setRecord_id(records.getRecord_id());
                messageMapper.addMessage(message);
            }
        }
        sendMessage(last_factory_id);
    }

    public void factoriesAndCarChoose(){
        List<Message> messages = messageMapper.getMessages();
        for(Message message : messages){
            List<Poi> tache3 = poiMapper.search_tache_factory(3,message.getIndustry_id());
            List<Poi> tache2 = poiMapper.search_tache_factory(2,message.getIndustry_id());
            List<Poi> tache1 = poiMapper.search_tache_factory(1,message.getIndustry_id());
            List<Car> cars = carMapper.getCars();
            //构建随机初始解
            List<Integer> solution = new ArrayList<>();
            solution.add(random.nextInt(tache3.size()));
            solution.add(random.nextInt(tache2.size()));
            solution.add(random.nextInt(tache1.size()));
            solution.add(random.nextInt(cars.size()));
            //计算初始代价
            double need_remain = message.getGoods_weight_remain();
            int end_id = message.getDestination();
            double cost = computeCost(tache3,tache2,tache1,cars,solution,need_remain,end_id);
            //模拟退火
            Solutions best_solutions = SA(tache3,tache2,tache1,cars,solution,need_remain,end_id,cost,700000,10,50000);
            List<Integer> best_solution = best_solutions.getSolution();
            double min_cost = best_solutions.getCost();
            //保底机制
            if(min_cost > cost){
                min_cost = cost;
                best_solution = solution;
            }
            //提取信息并传输至前端
            List<List<Poi>> ALL = new ArrayList<>();
            ALL.add(tache3);
            ALL.add(tache2);
            ALL.add(tache1);
            List<Integer> route = new ArrayList<>();
            route.add(end_id);
            for(int i = 0;i < 3;i++){
                if(best_solution.get(i) != -1)
                    route.add(ALL.get(i).get(best_solution.get(i)).getPoi_id());
                else
                    route.add(-1);
            }
            List<String> goods = new ArrayList<>();
            for(int i = 0;i < 3;i++){
                if(best_solution.get(i) != -1)
                    goods.add(goods_messageMapper.get_goods_type(ALL.get(i).get(best_solution.get(i)).getIndustry_id(),3-i));
                else
                    goods.add("NULL");
            }
            Map<String,Object> route_message = new HashMap<>();
            route_message.put("messageId",message.getMessage_id());
            route_message.put("carId",cars.get(best_solution.get(3)).getCar_id());
            route_message.put("route",route);
            route_message.put("goods",goods);
            route_message.put("refuseOrNot",1);
            sendMessage(route_message);
            //控制台打印消息
            System.out.println("第 "+message.getMessage_id()+" 条需求选择了第 "+cars.get(best_solution.get(3)).getCar_id()+" 辆车，路线是 "+route.get(3)+"->"+route.get(2)+"->"+route.get(1)+"->"+route.get(0));
            System.out.println("第 "+message.getMessage_id()+" 条需求是完成第 "+message.getIndustry_id()+" 条生成链，运输货物是 "+goods);
            //更新数据库,message表的余量、代价、空跑比*空跑距离，各个途经点的库存，owner表的记录，car表的车辆使用情况
            double load_m = car_messageMapper.selectLoad(cars.get(best_solution.get(3)).getCar_id());
            double goods3;
            double empty_distance;
            int wait_time;
            if(best_solution.get(1) != -1){
                if(best_solution.get(2) != -1){
                    wait_time = 3;
                    empty_distance = distanceMapper.getDistance(cars.get(best_solution.get(3)).getPoi_id(),tache1.get(best_solution.get(2)).getPoi_id());
                    double real_need1 = need_remain / tache3.get(best_solution.get(0)).getTransformation_rate() / tache2.get(best_solution.get(1)).getTransformation_rate();
                    double goods1 = Math.min(Math.min(load_m,tache1.get(best_solution.get(2)).getOut_stock()),real_need1);
                    empty_distance = empty_distance + (load_m-goods1) / load_m * distanceMapper.getDistance(tache1.get(best_solution.get(2)).getPoi_id(),tache2.get(best_solution.get(1)).getPoi_id());
                    poiMapper.change_out_stock0(goods1,tache1.get(best_solution.get(2)).getPoi_id());
                    double real_need2 = need_remain / tache3.get(best_solution.get(0)).getTransformation_rate();
                    double goods2 = Math.min(Math.min(load_m,goods1 * tache2.get(best_solution.get(1)).getTransformation_rate() + tache2.get(best_solution.get(1)).getOut_stock()),real_need2);
                    empty_distance = empty_distance + (load_m-goods2) / load_m * distanceMapper.getDistance(tache2.get(best_solution.get(1)).getPoi_id(),tache3.get(best_solution.get(0)).getPoi_id());
                    poiMapper.change_out_stock(goods1,goods2,tache2.get(best_solution.get(1)).getPoi_id());
                    goods3 = Math.min(Math.min(load_m,goods2 * tache3.get(best_solution.get(0)).getTransformation_rate() + tache3.get(best_solution.get(0)).getOut_stock()),need_remain);
                    empty_distance = empty_distance + (load_m-goods3) / load_m * distanceMapper.getDistance(tache3.get(best_solution.get(0)).getPoi_id(),end_id);
                    poiMapper.change_out_stock(goods2,goods3,tache3.get(best_solution.get(0)).getPoi_id());
                    ownersMapper.setOwners(message.getMessage_id(), tache3.get(best_solution.get(0)).getPoi_id(),tache2.get(best_solution.get(1)).getPoi_id(),tache1.get(best_solution.get(2)).getPoi_id(),cars.get(best_solution.get(3)).getCar_id(),1,wait_time);
                }
                else {
                    wait_time = 2;
                    empty_distance = distanceMapper.getDistance(cars.get(best_solution.get(3)).getPoi_id(),tache2.get(best_solution.get(1)).getPoi_id());
                    double real_need2 = need_remain / tache3.get(best_solution.get(0)).getTransformation_rate();
                    double goods2 = Math.min(Math.min(load_m,tache2.get(best_solution.get(1)).getOut_stock()),real_need2);
                    empty_distance = empty_distance + (load_m-goods2) / load_m * distanceMapper.getDistance(tache2.get(best_solution.get(1)).getPoi_id(),tache3.get(best_solution.get(0)).getPoi_id());
                    poiMapper.change_out_stock(0,goods2,tache2.get(best_solution.get(1)).getPoi_id());
                    goods3 = Math.min(Math.min(load_m,goods2 * tache3.get(best_solution.get(0)).getTransformation_rate() + tache3.get(best_solution.get(0)).getOut_stock()),need_remain);
                    empty_distance = empty_distance + (load_m-goods3) / load_m * distanceMapper.getDistance(tache3.get(best_solution.get(0)).getPoi_id(),end_id);
                    poiMapper.change_out_stock(goods2,goods3,tache3.get(best_solution.get(0)).getPoi_id());
                    ownersMapper.setOwners(message.getMessage_id(), tache3.get(best_solution.get(0)).getPoi_id(),tache2.get(best_solution.get(1)).getPoi_id(),-1,cars.get(best_solution.get(3)).getCar_id(),1,wait_time);
                }
            }
            else {
                wait_time = 1;
                empty_distance = distanceMapper.getDistance(cars.get(best_solution.get(3)).getPoi_id(),tache3.get(best_solution.get(0)).getPoi_id());
                goods3 = Math.min(Math.min(load_m,tache3.get(best_solution.get(0)).getOut_stock()),need_remain);
                empty_distance = empty_distance + (load_m-goods3) / load_m * distanceMapper.getDistance(tache3.get(best_solution.get(0)).getPoi_id(),end_id);
                poiMapper.change_out_stock(0,goods3,tache3.get(best_solution.get(0)).getPoi_id());
                ownersMapper.setOwners(message.getMessage_id(), tache3.get(best_solution.get(0)).getPoi_id(),-1,-1,cars.get(best_solution.get(3)).getCar_id(),1,wait_time);
            }
            poiMapper.change_in_stock(goods3,end_id);
            messageMapper.setEmptyDistance(message.getMessage_id(), 3.5 * empty_distance);
            messageMapper.changeRemain(message.getMessage_id(),goods3);
            messageMapper.changeMessage(message.getMessage_id(), min_cost);
            carMapper.changeCar(cars.get(best_solution.get(3)).getCar_id(),message.getMessage_id());
            //判断该需求是否被完成
            if(goods3 >= need_remain){
                messageMapper.setCan_be_done1(message.getMessage_id());
            }
        }
    }

    public double computeCost(List<Poi> tache3,List<Poi> tache2,List<Poi> tache1,List<Car> cars,List<Integer> solution,double need_remain,int end_id){
        List<Poi> route = new ArrayList<>();
        List<Double> percent = new ArrayList<>();
        Car car = cars.get(solution.get(3));
        double load_m = car_messageMapper.selectLoad(car.getCar_id());
        route.add(tache3.get(solution.get(0)));
        if(solution.get(1) != -1){
            route.add(tache2.get(solution.get(1)));
            if (solution.get(2) != -1){
                route.add(tache1.get(solution.get(2)));
                double real_need1 = need_remain / tache3.get(solution.get(0)).getTransformation_rate() / tache2.get(solution.get(1)).getTransformation_rate();
                double truly_goods1 = Math.min(Math.min(real_need1,load_m),tache1.get(solution.get(2)).getOut_stock());
                double percent1 = truly_goods1 / load_m;
                double real_need2 = need_remain / tache3.get(solution.get(0)).getTransformation_rate();
                double truly_goods2 = Math.min(Math.min(truly_goods1 * tache2.get(solution.get(1)).getTransformation_rate()+tache2.get(solution.get(1)).getOut_stock(),load_m),real_need2);
                double percent2 = truly_goods2 / load_m;
                double truly_goods3 = Math.min(Math.min(load_m,truly_goods2 * tache3.get(solution.get(0)).getTransformation_rate()+tache3.get(solution.get(0)).getOut_stock()),need_remain);
                double percent3 = truly_goods3 / load_m;
                percent.add(percent3);
                percent.add(percent2);
                percent.add(percent1);
            }
            else {
                double real_need2 = need_remain / tache3.get(solution.get(0)).getTransformation_rate();
                double truly_goods2 = Math.min(Math.min(tache2.get(solution.get(1)).getOut_stock(),load_m),real_need2);
                double percent2 = truly_goods2 / load_m;
                double truly_goods3 = Math.min(Math.min(load_m,truly_goods2 * tache3.get(solution.get(0)).getTransformation_rate()+tache3.get(solution.get(0)).getOut_stock()),need_remain);
                double percent3 = truly_goods3 / load_m;
                percent.add(percent3);
                percent.add(percent2);
            }
        }
        else {
            double truly_goods3 = Math.min(Math.min(load_m,tache3.get(solution.get(0)).getOut_stock()),need_remain);
            double percent3 = truly_goods3 / load_m;
            percent.add(percent3);
        }
        //System.out.println(car.getPoi_id()+"   "+route.get(route.size()-1).getPoi_id());
        double jieDanCost = 1.6*distanceMapper.getDuration(car.getPoi_id(),route.get(route.size()-1).getPoi_id());
        double emptyRunningCost = 3.5*distanceMapper.getDistance(car.getPoi_id(),route.get(route.size()-1).getPoi_id());
        int end = end_id;
        for(int i = 0;i < route.size();i++){
            emptyRunningCost = emptyRunningCost + 3.5*(1-percent.get(i))*distanceMapper.getDistance(route.get(i).getPoi_id(),end);
            end = route.get(i).getPoi_id();
        }
        double money = 10*Math.sqrt(distanceMapper.getDuration(route.get(route.size()-1).getPoi_id(),end_id));
        return jieDanCost + emptyRunningCost - money + 0.5*poiMapper.getIntegrations(end_id);
    }

    public void factoriesAndCarChoose2(){
        List<Message> messages = messageMapper.getMessages();
        for(Message message : messages){
            int end_id = message.getDestination();
            int industry_id = message.getIndustry_id();
            double need_remain = message.getGoods_weight_remain();
            //根据终点选取依据代价函数的部分独立特征表达式激活的tache3
            List<ChildPoi> tache3 = poiMapper.search_next_tache_factory(3,industry_id,end_id,need_remain, poiMapper.search_next_tache_factory_num(3,industry_id,end_id)/2+1);
            //构建初始随机解的一部分
            List<Integer> solution = new ArrayList<>();
            List<ChildPoi> route = new ArrayList<>();
            ChildCar car = new ChildCar();
            solution.add(random.nextInt(tache3.size()));
            //取出该解，将它作为终点激活tache2（如果需求货物或者车辆最大载重没被满足）
            ChildPoi tache_3 = tache3.get(solution.get(0));
            route.add(tache_3);
            //仅tache3即可满足需求or车辆（44是车辆载重的中位数）
            if(tache_3.getOut_stock() >= need_remain || tache_3.getOut_stock() >= 44.0){
                //不找tache2、1
                solution.add(-1);
                route.add(null);
                solution.add(-1);
                route.add(null);
                //找车
                List<ChildCar> cars = carMapper.search_part_cars(tache_3.getPoi_id(),need_remain);
                solution.add(random.nextInt(cars.size()));
                car = cars.get(solution.get(3));
            }
            //不能满足，激活tache2,采取的策略是在tache2尽量运为满足需求更多的货物而不是仅仅补tache3不能满足的部分，可以减少空跑率
            else {
                double need_remain2 = need_remain / tache_3.getTransformation_rate();
                List<ChildPoi> tache2 = poiMapper.search_next_tache_factory(2,industry_id,tache_3.getPoi_id(),need_remain2, poiMapper.search_next_tache_factory_num(2,industry_id,tache_3.getPoi_id())/2+1);
                solution.add(random.nextInt(tache2.size()));
                ChildPoi tache_2 = tache2.get(solution.get(1));
                route.add(tache_2);
                //同理，判断激活的tache2工厂需不需要激活下一级工厂，还是直接选车
                if(tache_2.getOut_stock() >= need_remain2 || tache_2.getOut_stock() >= 44){
                    solution.add(-1);
                    route.add(null);
                    List<ChildCar> cars = carMapper.search_part_cars(tache_2.getPoi_id(),need_remain2);
                    solution.add(random.nextInt(cars.size()));
                    car = cars.get(solution.get(3));
                }
                else {
                    double need_remain3 = need_remain2 / tache_2.getTransformation_rate();
                    List<ChildPoi> tache1 = poiMapper.search_next_tache_factory(1,industry_id,tache_2.getPoi_id(),need_remain3, poiMapper.search_next_tache_factory_num(1,industry_id,tache_2.getPoi_id())/2+1);
                    solution.add(random.nextInt(tache1.size()));
                    ChildPoi tache_1 = tache1.get(solution.get(2));
                    route.add(tache_1);
                    List<ChildCar> cars = carMapper.search_part_cars(tache_1.getPoi_id(),need_remain3);
                    solution.add(random.nextInt(cars.size()));
                    car = cars.get(solution.get(3));
                }
            }
//            System.out.println(solution);
            //计算初始代价
            double cost = computeCost2(solution,end_id,need_remain,route,car);
//            System.out.println(solution);
            //动态匹配退火温度
            Map<String,Double> ts = generateT(industry_id);
            double t = ts.get("t");
            double t_low = ts.get("t_low");
            double trs = ts.get("trs");
            //模拟退火
            List<Solution> solutions = SA2(tache3,solution,cost,route,car,need_remain,industry_id,end_id,t,t_low,trs);
            //模拟司机拒绝
            Solution best_solution = new Solution();
            if(random.nextDouble() < 0.1){
                carMapper.changeCar(solutions.get(0).getCar().getCar_id(),-1); // 惩罚拒绝车辆不参与当前轮次
                System.out.println("车辆"+solutions.get(0).getCar().getCar_id()+"拒绝接单，将询问次优解");
                Map<String,Object> refuse_message = new HashMap<>();
                refuse_message.put("messageId",message.getMessage_id());
                refuse_message.put("carId",solutions.get(0).getCar().getCar_id());
                refuse_message.put("refuseOrNot",0);
                sendMessage(refuse_message);
                if (random.nextDouble() < 0.1){
                    carMapper.changeCar(solutions.get(1).getCar().getCar_id(),-1);
                    System.out.println("车辆"+solutions.get(1).getCar().getCar_id()+"拒绝接单，将启用次次优解");
                    refuse_message.put("carId",solutions.get(1).getCar().getCar_id());
                    sendMessage(refuse_message);
                    best_solution = solutions.get(2);
                }
                else {
                    System.out.println("启用次优解");
                    best_solution = solutions.get(1);
                }
            }
            else {
                best_solution = solutions.get(0);
            }
            //提取信息并传输至前端
            List<Integer> routes = new ArrayList<>();
            routes.add(end_id);
            for(int i = 0;i < 3;i++){
                if(best_solution.getSolution().get(i) != -1)
                    routes.add(best_solution.getRoute().get(i).getPoi_id());
                else
                    routes.add(-1);
            }
            List<String> goods = new ArrayList<>();
            for(int i = 0;i < 3;i++){
                if(best_solution.getSolution().get(i) != -1)
                    goods.add(goods_messageMapper.get_goods_type(best_solution.getRoute().get(i).getIndustry_id(),3-i));
                else
                    goods.add("NULL");
            }
            Map<String,Object> route_message = new HashMap<>();
            route_message.put("messageId",message.getMessage_id());
            route_message.put("carId",best_solution.getCar().getCar_id());
            route_message.put("route",routes);
            route_message.put("industryId",message.getIndustry_id());
            route_message.put("goods",goods);
            route_message.put("refuseOrNot",1);
            sendMessage(route_message);
            //控制台打印消息
            System.out.println("第 "+message.getMessage_id()+" 条需求选择了第 "+best_solution.getCar().getCar_id()+" 辆车，路线是 "+routes.get(3)+"->"+routes.get(2)+"->"+routes.get(1)+"->"+routes.get(0));
            System.out.println("第 "+message.getMessage_id()+" 条需求是完成第 "+message.getIndustry_id()+" 条生成链，运输货物是 "+goods);
            //更新数据库,message表的余量、代价、空跑比*空跑距离，各个途经点的库存，owner表的记录，car表的车辆使用情况
            double goods3 = updateData(best_solution.getSolution(),best_solution.getRoute(),best_solution.getCar(), best_solution.getCost(), need_remain, message);
            poiMapper.change_in_stock(goods3,end_id);
            //判断该需求是否被完成
            if(goods3 >= need_remain){
                messageMapper.setCan_be_done1(message.getMessage_id());
            }
        }
        accept_refused_cars();// 释放拒绝车辆
    }

    public Map<String,Double> generateT(int industry_id){
        double t = 0,t_low = 0;
        double trs = 0;
        //动态匹配退火温度
        switch (industry_id){
            case 1:{
                t = 50000;
                t_low = 10;
                trs = 5000;
                break;
            }
            case 2:{
                t = 40000;
                t_low = 10;
                trs = 4000;
                break;
            }
            case 3:{
                t = 32500;
                t_low = 10;
                trs = 3250;
                break;
            }
            case 4:{
                t = 90000;
                t_low = 10;
                trs = 9000;
                break;
            }
        }
        Map<String,Double> Ts = new HashMap<>();
        Ts.put("t",t);
        Ts.put("t_low",t_low);
        Ts.put("trs",trs);
        return Ts;
    }

    public double updateData(List<Integer> best_solution,List<ChildPoi> route,ChildCar car,double min_cost,double need_remain,Message message){
        double goods3;
        double empty_distance = car.getDistance();//车到起点的空跑量
        int wait_time = 1;
        if(best_solution.get(1) != -1){
            wait_time++;
            if(best_solution.get(2) != -1){
                wait_time++;
                double real_need1 = need_remain / route.get(0).getTransformation_rate() / route.get(1).getTransformation_rate();
                double goods1 = Math.min(Math.min(car.getLoad_m(),route.get(2).getOut_stock()),real_need1);
                empty_distance = empty_distance + (car.getLoad_m()-goods1) / car.getLoad_m() * route.get(2).getDistance(); //tache1到tache2的空跑量
                poiMapper.change_out_stock0(goods1,route.get(2).getPoi_id());//修改tache1对应工厂库存
                double real_need2 = need_remain / route.get(0).getTransformation_rate();
                double goods2 = Math.min(Math.min(car.getLoad_m(),goods1 * route.get(1).getTransformation_rate() + route.get(1).getOut_stock()),real_need2);
                empty_distance = empty_distance + (car.getLoad_m()-goods2) / car.getLoad_m() * route.get(1).getDistance();//tache2到tache3的空跑量
                poiMapper.change_out_stock(goods1,goods2,route.get(1).getPoi_id());//修改tache2对应工厂库存
                goods3 = Math.min(Math.min(car.getLoad_m(),goods2 * route.get(0).getTransformation_rate() + route.get(0).getOut_stock()),need_remain);
                empty_distance = empty_distance + (car.getLoad_m()-goods3) / car.getLoad_m() * route.get(0).getDistance();//tache3到tache4的空跑量
                poiMapper.change_out_stock(goods2,goods3,route.get(0).getPoi_id());//修改tache3对应工厂库存
                ownersMapper.setOwners(message.getMessage_id(), route.get(0).getPoi_id(),route.get(1).getPoi_id(),route.get(2).getPoi_id(),car.getCar_id(),1,wait_time);
            }
            else {
                double real_need2 = need_remain / route.get(0).getTransformation_rate();
                double goods2 = Math.min(Math.min(car.getLoad_m(),route.get(1).getOut_stock()),real_need2);
                empty_distance = empty_distance + (car.getLoad_m()-goods2) / car.getLoad_m() * route.get(1).getDistance();
                poiMapper.change_out_stock(0,goods2,route.get(1).getPoi_id());
                goods3 = Math.min(Math.min(car.getLoad_m(),goods2 * route.get(0).getTransformation_rate() + route.get(0).getOut_stock()),need_remain);
                empty_distance = empty_distance + (car.getLoad_m()-goods3) / car.getLoad_m() * route.get(0).getDistance();
                poiMapper.change_out_stock(goods2,goods3,route.get(0).getPoi_id());
                ownersMapper.setOwners(message.getMessage_id(), route.get(0).getPoi_id(),route.get(1).getPoi_id(),-1,car.getCar_id(),1,wait_time);
            }
        }
        else {
            goods3 = Math.min(Math.min(car.getLoad_m(),route.get(0).getOut_stock()),need_remain);
            empty_distance = empty_distance + (car.getLoad_m()-goods3) / car.getLoad_m() * route.get(0).getDistance();
            poiMapper.change_out_stock(0,goods3,route.get(0).getPoi_id());
            ownersMapper.setOwners(message.getMessage_id(), route.get(0).getPoi_id(),-1,-1,car.getCar_id(),1,wait_time);
        }
        messageMapper.setEmptyDistance(message.getMessage_id(), 3.5 * empty_distance);
        messageMapper.changeRemain(message.getMessage_id(),goods3);
        messageMapper.changeMessage(message.getMessage_id(), min_cost);
        carMapper.changeCar(car.getCar_id(),message.getMessage_id());
        return goods3;
    }

    public double computeCost2(List<Integer> solution,int end_id,double need_remain,List<ChildPoi> route,ChildCar car){
        double jieDanCost = 1.6 * car.getDuration();
        double emptyRunningCost = 3.5 * car.getDistance();
        double money;
        double satisfaction_rate;
        if(solution.get(1) != -1){
            if(solution.get(2) != -1){
                double real_need1 = need_remain / route.get(0).getTransformation_rate() / route.get(1).getTransformation_rate();
                double real_goods1 = Math.min(Math.min(real_need1,route.get(2).getOut_stock()),car.getLoad_m());
                double empty_percent1 = 1 - real_goods1 / car.getLoad_m();
                emptyRunningCost = emptyRunningCost + 3.5 * empty_percent1 * route.get(2).getDistance();
                double real_need2 = need_remain / route.get(0).getTransformation_rate();
                double real_goods2 = Math.min(Math.min(real_need2,route.get(1).getOut_stock()+real_goods1 * route.get(1).getTransformation_rate()),car.getLoad_m());
                double empty_percent2 = 1 - real_goods2 / car.getLoad_m();
                emptyRunningCost = emptyRunningCost + 3.5 * empty_percent2 * route.get(1).getDistance();
                double real_goods3 = Math.min(Math.min(need_remain,route.get(0).getOut_stock()+real_goods2 * route.get(0).getTransformation_rate()),car.getLoad_m());
                double empty_percent3 = 1 - real_goods3 / car.getLoad_m();
                emptyRunningCost = emptyRunningCost + 3.5 * empty_percent3 * route.get(0).getDistance();
                money = 7 * Math.sqrt(distanceMapper.getDuration(route.get(2).getPoi_id(),end_id));
                satisfaction_rate = real_goods3 / need_remain;
            }
            else {
                double real_need2 = need_remain / route.get(0).getTransformation_rate();
                double real_goods2 = Math.min(Math.min(real_need2,route.get(1).getOut_stock()),car.getLoad_m());
                double empty_percent2 = 1 - real_goods2 / car.getLoad_m();
                emptyRunningCost = emptyRunningCost + 3.5 * empty_percent2 * route.get(1).getDistance();
                double real_goods3 = Math.min(Math.min(need_remain,route.get(0).getOut_stock()+real_goods2 * route.get(0).getTransformation_rate()),car.getLoad_m());
                double empty_percent3 = 1 - real_goods3 / car.getLoad_m();
                emptyRunningCost = emptyRunningCost + 3.5 * empty_percent3 * route.get(0).getDistance();
                money = 7 * Math.sqrt(distanceMapper.getDuration(route.get(1).getPoi_id(),end_id));
                satisfaction_rate = real_goods3 / need_remain;
            }
        }
        else{
            double real_goods3 = Math.min(Math.min(need_remain,route.get(0).getOut_stock()),car.getLoad_m());
            double empty_percent3 = 1 - real_goods3 / car.getLoad_m();
            emptyRunningCost = emptyRunningCost + 3.5 * empty_percent3 * route.get(0).getDistance();
            money = 7 * Math.sqrt(distanceMapper.getDuration(route.get(0).getPoi_id(),end_id));
            satisfaction_rate = real_goods3 / need_remain;
        }
        return (1.5-satisfaction_rate) * (jieDanCost + emptyRunningCost - money + 0.5*poiMapper.getIntegrations(end_id));
    }


    public List<Solution> SA2(List<ChildPoi> tache3,List<Integer> best_solution,double min_cost,List<ChildPoi> first_route,ChildCar first_car,double need_remain,int industry_id,int end_id,double t, double t_low, double trs){
        double t_highOrLow = t / 10; // 定义低温与高温的分界线
        double cost;
        ChildCar car = new ChildCar();
        List<Solution> solutions  = new ArrayList<>(); //维护一个列表依次存储最优解，次优解，次次优解
        //初始解入列表
        Solution s = new Solution();
        s.setCost(min_cost);
        s.setCar(first_car);
        s.setRoute(first_route);
        s.setSolution(best_solution);
        solutions.add(s);
        for(;t>0;t=t-t_low){
            List<Integer> solution = new ArrayList<>();
            List<ChildPoi> route = new ArrayList<>();
            //高温时同时跳变线路上的所有工厂和选取车辆
            if(t > t_highOrLow){
                // 跳变tache3工厂
                int jump = random.nextInt((int)Math.ceil(t/trs))+1;
//                System.out.println("dx "+tache3.size());//
                int new_index = jumping2(best_solution.get(0),jump,tache3.size());
//                System.out.println("新的 "+new_index);//
                solution.add(new_index);
//                System.out.println(solution);//
                ChildPoi tache_3 = tache3.get(solution.get(0));
                route.add(tache_3);
                //仅tache3即可满足需求or车辆（44是车辆载重的中位数）
                if(tache_3.getOut_stock() >= need_remain || tache_3.getOut_stock() >= 44.0){
                    //不找tache2、1
                    solution.add(-1);
                    route.add(null);
                    solution.add(-1);
                    route.add(null);
                    //激活车
                    List<ChildCar> cars = carMapper.search_part_cars(tache_3.getPoi_id(),need_remain);
                    //跳变车
                    solution.add(jumping2(random.nextInt(cars.size()),random.nextInt((int)Math.ceil(t/trs))+1,cars.size()));
                    car = cars.get(solution.get(3));
                }
                //不能满足，激活tache2,采取的策略是在tache2尽量运为满足需求更多的货物而不是仅仅补tache3不能满足的部分，可以减少空跑率
                else {
                    double need_remain2 = need_remain / tache_3.getTransformation_rate();
                    List<ChildPoi> tache2 = poiMapper.search_next_tache_factory(2,industry_id,tache_3.getPoi_id(),need_remain2, poiMapper.search_next_tache_factory_num(2,industry_id,tache_3.getPoi_id())/2+1);
                    //跳变tache2
//                    System.out.println("大小 "+tache2.size());//
                    int new_index2 = jumping2(random.nextInt(tache2.size()),random.nextInt((int)Math.ceil(t/trs))+1,tache2.size());
//                    System.out.println("新的 "+new_index2);//
                    solution.add(new_index2);
//                    System.out.println(solution);//
                    ChildPoi tache_2 = tache2.get(solution.get(1));
                    route.add(tache_2);
                    //同理，判断激活的tache2工厂需不需要激活下一级工厂，还是直接选车
                    if(tache_2.getOut_stock() >= need_remain2 || tache_2.getOut_stock() >= 44){
                        solution.add(-1);
                        route.add(null);
                        List<ChildCar> cars = carMapper.search_part_cars(tache_2.getPoi_id(),need_remain2);
                        solution.add(jumping2(random.nextInt(cars.size()),random.nextInt((int)Math.ceil(t/trs))+1,cars.size()));
                        car = cars.get(solution.get(3));
                    }
                    else {
                        double need_remain3 = need_remain2 / tache_2.getTransformation_rate();
                        List<ChildPoi> tache1 = poiMapper.search_next_tache_factory(1,industry_id,tache_2.getPoi_id(),need_remain3, poiMapper.search_next_tache_factory_num(1,industry_id,tache_2.getPoi_id())/2+1);
                        //跳变tache1
//                        System.out.println("大小 "+tache1.size());//
                        int new_index3 = jumping2(random.nextInt(tache1.size()),random.nextInt((int)Math.ceil(t/trs))+1,tache1.size());
//                        System.out.println("新index "+new_index3);//
                        solution.add(new_index3);
//                        System.out.println(solution);//
                        ChildPoi tache_1 = tache1.get(solution.get(2));
                        route.add(tache_1);
                        List<ChildCar> cars = carMapper.search_part_cars(tache_1.getPoi_id(),need_remain3);
//                        System.out.println("大小 "+cars.size());//
                        int new_index4 = jumping2(random.nextInt(cars.size()),random.nextInt((int)Math.ceil(t/trs))+1,cars.size());
//                        System.out.println("新index "+new_index4);//
                        solution.add(new_index4);
//                        System.out.println(solution);//
                        car = cars.get(solution.get(3));
                    }
                }
            }
            //低温时仅跳变源头工厂和车辆
            else {
                solution.add(best_solution.get(0));
                route.add(s.getRoute().get(0));
                solution.add(best_solution.get(1));
                route.add(s.getRoute().get(1));
                //源头工厂选了才跳
                if(best_solution.get(2) != -1){
                    ChildPoi tache_2 = route.get(1);
                    double need_remain3 = need_remain / route.get(0).getTransformation_rate() / route.get(1).getTransformation_rate();
                    List<ChildPoi> tache1 = poiMapper.search_next_tache_factory(1,industry_id,tache_2.getPoi_id(),need_remain3, poiMapper.search_next_tache_factory_num(1,industry_id,tache_2.getPoi_id())/2+1);
                    solution.add(jumping2(best_solution.get(2),random.nextInt((int)Math.ceil(t/trs))+1,tache1.size()));
                    ChildPoi tache_1 = tache1.get(solution.get(2));
                    route.add(tache_1);
                    List<ChildCar> cars = carMapper.search_part_cars(tache_1.getPoi_id(),need_remain3);
                    solution.add(jumping2(random.nextInt(cars.size()),random.nextInt((int)Math.ceil(t/trs))+1,cars.size()));
                    car = cars.get(solution.get(3));
                }
                //否则只跳变车
                else {
                    solution.add(-1);
                    route.add(null);
                    //找到车的激活工厂并激活车的解空间
                    if(best_solution.get(1) != -1){
                        ChildPoi tache_2 = route.get(1);
                        double need_remain2 = need_remain / route.get(0).getTransformation_rate();
                        List<ChildCar> cars = carMapper.search_part_cars(tache_2.getPoi_id(),need_remain2);
                        //跳变车
                        solution.add(jumping2(best_solution.get(3),random.nextInt((int)Math.ceil(t/trs))+1,cars.size()));
                        car = cars.get(solution.get(3));
                    }
                    else {
                        ChildPoi tache_3 = route.get(0);
                        List<ChildCar> cars = carMapper.search_part_cars(tache_3.getPoi_id(),need_remain);
                        //跳变车
                        solution.add(jumping2(best_solution.get(3),random.nextInt((int)Math.ceil(t/trs))+1,cars.size()));
                        car = cars.get(solution.get(3));
                    }
                }
            }
            cost = computeCost2(solution,end_id,need_remain,route,car);
            //无条件接受更优解
            if(cost < min_cost){
                best_solution = solution;
                min_cost = cost;
                //将更优解入列表
                int t_f = 0;
                for(int i = 0;i < solutions.size();i++){
                    if(min_cost < solutions.get(i).getCost()){
                        s.setSolution(best_solution);
                        s.setCost(min_cost);
                        s.setRoute(route);
                        s.setCar(car);
                        solutions.add(i,s);
                        t_f = 1;
                        break;
                    }
                }
                if(t_f == 0 && solutions.size() < 3){
                    s.setSolution(best_solution);
                    s.setCost(min_cost);
                    s.setRoute(route);
                    s.setCar(car);
                    solutions.add(s);
                }
                if(solutions.size() > 3)
                    solutions.remove(solutions.size()-1); // 次次次优解，出列！忠！诚！
            }
            else {
                //以e^((min_cost-cost)/t)的概率接受劣解以跳出局部最优
                if(random.nextDouble() < Math.exp((min_cost-cost)/t)) {
                    min_cost = cost;
                    best_solution = solution;
                    s.setSolution(best_solution);
                    s.setCost(min_cost);
                    s.setRoute(route);
                    s.setCar(car);
                }
            }
        }
        return solutions;
    }


    public Solutions SA(List<Poi> tache3, List<Poi> tache2, List<Poi> tache1, List<Car> cars, List<Integer> best_solution, double need_remain, int end_id, double min_cost, double t, double t_low, int trs){
        double t_highOrLow = t / 10; // 定义低温与高温的分界线
        List<Integer> lengths = new ArrayList<>();
        lengths.add(tache3.size()-1);
        lengths.add(tache2.size()-1);
        lengths.add(tache1.size()-1);
        lengths.add(cars.size()-1);
        for(;t>0;t=t-t_low){
            //高温时同时跳变线路上的所有工厂和选取车辆
            if(t > t_highOrLow) {
                List<Integer> jumps = new ArrayList<>();
                //根据当前退火温度生成随机跳变值
                for(int i = 0;i < 4;i++)
                    jumps.add(random.nextInt((int)Math.ceil(t/trs))+1);
                List<Integer> solution = new ArrayList<>(best_solution);
                //跳变
                solution = jumping(solution,jumps,lengths);
                //截断解
                solution = cutRoute(solution,tache3,tache2,cars,need_remain);
                double cost = computeCost(tache3,tache2,tache1,cars,solution,need_remain,end_id);
                //无条件接受最优解
                if(cost < min_cost) {
                    best_solution = solution;
                    min_cost = cost;
                }
                else {
                    //以e^((min_cost-cost)/t)的概率接受劣解以跳出局部最优
                    if(random.nextDouble() < Math.exp((min_cost-cost)/t)) {
                        min_cost = cost;
                        best_solution = solution;
                    }
                }
            }
            //低温时仅跳变源头工厂和车辆
            else {
                List<Integer> jumps = new ArrayList<>();
                List<Integer> solution = new ArrayList<>(best_solution);
                if(solution.get(2) != -1){
                    for(int i = 0;i < 3;i++)
                        jumps.add(0);
                    jumps.add(random.nextInt((int)Math.ceil(t/trs))+1);
                }
                else {
                    jumps.add(0);
                    jumps.add(0);
                    jumps.add(random.nextInt((int)Math.ceil(t/trs))+1);
                    jumps.add(random.nextInt((int)Math.ceil(t/trs))+1);
                }
                //跳变
                solution = jumping(solution,jumps,lengths);
                double cost = computeCost(tache3,tache2,tache1,cars,solution,need_remain,end_id);
                //无条件接受最优解
                if(cost < min_cost) {
                    best_solution = solution;
                    min_cost = cost;
                }
                else {
                    //以e^((min_cost-cost)/t)的概率接受劣解以跳出局部最优
                    if(random.nextDouble() < Math.exp((min_cost-cost)/t)) {
                        min_cost = cost;
                        best_solution = solution;
                    }
                }
            }
        }
        Solutions solutions = new Solutions();
        solutions.setSolution(best_solution);
        solutions.setCost(min_cost);
        return solutions;
    }

    public List<Integer> jumping(List<Integer> solution,List<Integer> jumps,List<Integer> lengths){
        for(int i = 0;i < 4;i++) {
            if (solution.get(i) == 0)
                solution.set(i,Math.min(jumps.get(i),lengths.get(i)));
            else {
                if (solution.get(i).equals(lengths.get(i)))
                    solution.set(i,Math.max(0,lengths.get(i)-jumps.get(i)));
                else {
                    int left_or_right = random.nextInt(2);
                    if (left_or_right == 0)
                        solution.set(i,Math.max(0,solution.get(i)-jumps.get(i)));
                    else
                        solution.set(i,Math.min(solution.get(i)+jumps.get(i),lengths.get(i)));
                }
            }
        }
        return solution;
    }

    public int jumping2(int index,int jump,int length){
        if(index == 0)
            return Math.min(length - 1,jump);
        if(index == length - 1)
            return Math.max(0,index - jump);
        int left_or_right = random.nextInt(2);
        if (left_or_right == 0)
            return Math.max(0,index - jump);
        return Math.min(length - 1,index + jump);
    }

    public List<Integer> cutRoute(List<Integer> solution, List<Poi> tache3, List<Poi> tache2, List<Car> cars, double need_remain){
        Car car = cars.get(solution.get(3));
        double load_m = car_messageMapper.selectLoad(car.getCar_id());
        //如果tache3的节点库存就可以满足需求或把车填满就不去2，1的节点
        if(tache3.get(solution.get(0)).getOut_stock() >= Math.min(need_remain,load_m)){
            solution.set(1,-1);
            solution.set(2,-1);
        }
        else {
            //如果tache2，3的库存可以满足需求或2可以填满车就不去1
            if(tache3.get(solution.get(0)).getOut_stock() + tache2.get(solution.get(1)).getOut_stock()*tache3.get(solution.get(0)).getTransformation_rate() >= need_remain || tache2.get(solution.get(1)).getOut_stock() >= load_m){
                solution.set(2,-1);
            }
        }
        return solution;
    }

    public boolean can_be_done_or_not(){
        List<Map<String,Object>> charges = messageMapper.messageCharge();
        boolean charge = true;
        for (Map<String,Object> row : charges){
            if(Integer.parseInt(row.get("can_be_done").toString()) != 1)
               return false;
        }
        return charge;
    }

    public void accept_refused_cars(){
        carMapper.acceptCars();
    }


    //    public void driverChoose(){
//            List<Map<String, Object>> messages = messageMapper.getMessages();
//            for(Map<String,Object> row : messages){
//                int need_goods_type = Integer.parseInt(row.get("need_goods_type").toString());
//                List<Map<String, Object>> owners = poiMapper.getOwners(need_goods_type);
//                row.put("owners",owners);
//                int destination = Integer.parseInt(row.get("destination").toString());
//                double integrations = poiMapper.getIntegrations(destination);
//                row.put("integration_distance",integrations);
//            }
//            List<Map<String, Object>> matches = messages;
//            for(Map<String,Object> row : matches){
//                List<Map<String, Object>> cars = carMapper.getCars();
//                List<Map<String, Object>> owners = (List<Map<String, Object>>) row.get("owners");
////                System.out.println(owners.size());
//                List<Map<String, Object>> solutions = generateSolutions(owners,cars);
//                int best_solution_id = random.nextInt(solutions.size());
//                Map<String,Object>  best_solution = solutions.get(best_solution_id);
//                double min_cost = computeCost(row,best_solution);
//                double SA_t = 0,t_low = 0;
//                int trs = 0;
//                switch (solutions.size()/1000){
//                    case 0:{
//                        SA_t = (solutions.size()-100)*10;
//                        t_low = 10;
//                        trs = solutions.size()-100;
//                        break;
//                    }
//                    case 1:{
//                        SA_t = (solutions.size()-400)*10;
//                        t_low = 10;
//                        trs = solutions.size()-400;
//                        break;
//                    }
//                    case 2:{
//                        SA_t = (solutions.size()-700)*10;
//                        t_low = 10;
//                        trs = solutions.size()-700;
//                        break;
//                    }
//                    case 3:{
//                        SA_t = (solutions.size()-1000)*10;
//                        t_low = 10;
//                        trs = solutions.size()-1000;
//                        break;
//                    }
//                    case 4:{
//                        SA_t = (solutions.size()-1300)*10;
//                        t_low = 10;
//                        trs = solutions.size()-1300;
//                        break;
//                    }
//                    case 5:{
//                        SA_t = (solutions.size()-1800)*10;
//                        t_low = 10;
//                        trs = solutions.size()-1800;
//                        break;
//                    }
//                    case 6:{
//                        SA_t = (solutions.size()-2500)*10;
//                        t_low = 10;
//                        trs = solutions.size()-2500;
//                        break;
//                    }
//                    case 7:{
//                        SA_t = (solutions.size()-3400)*10;
//                        t_low = 10;
//                        trs = solutions.size()-3400;
//                        break;
//                    }
//                }
//                Map<String,Object> bests = SA(solutions,best_solution_id,min_cost,row,SA_t,t_low,trs);
//                min_cost = Double.parseDouble(bests.get("min_cost").toString());
//                int car_id = Integer.parseInt(bests.get("car_id").toString());
//                int need_owner = Integer.parseInt(bests.get("need_owner").toString());
//                //判断司机是否拒绝接单
//                if(random.nextDouble()<0.90) {
//                    System.out.println("订单号：" + row.get("message_id") + " 的最优解是选择 " + need_owner + " 号取货点和 " + car_id + " 号车,开销为 " + min_cost);
//                    messageMapper.changeMessage(Integer.parseInt(row.get("message_id").toString()), min_cost);
//                    ownersMapper.setOwners(Integer.parseInt(row.get("message_id").toString()), need_owner, car_id,1);
//                    carMapper.changeCar(car_id, Integer.parseInt(row.get("message_id").toString()));
//                    double remain = Math.max(messageMapper.getRemain(Integer.parseInt(row.get("message_id").toString())) - car_messageMapper.selectLoad(car_id), 0);
//                    messageMapper.changeRemain(Integer.parseInt(row.get("message_id").toString()), remain);
//                    if (remain == 0) {
//                        messageMapper.setCan_be_done1(Integer.parseInt(row.get("message_id").toString()));
//                    } else {
//                        messageMapper.setCan_be_done0(Integer.parseInt(row.get("message_id").toString()));
//                    }
//                }
//                else {
//                    System.out.println("订单号：" + row.get("message_id") + " 的最优解是选择 " + need_owner + " 号取货点和 " + car_id + " 号车,但是司机拒绝接单");
//                    ownersMapper.setOwners(Integer.parseInt(row.get("message_id").toString()), need_owner, car_id,0);
//                    carMapper.changeCar(car_id, -1);
//                }
//            }
//
//    }
//
//    public List<Map<String, Object>> generateSolutions(List<Map<String, Object>> owners, List<Map<String, Object>> cars){
//        List<Map<String, Object>> solutions = new ArrayList<>();
//        for(Map<String,Object> row : owners){
//            for (Map<String,Object> row2 : cars) {
//                Map<String, Object> solution = new HashMap<>();
//                solution.put("need_owner",row.get("poi_id"));
//                solution.put("car_id",row2.get("car_id"));
//                solutions.add(solution);
//            }
//        }
//        return solutions;
//    }
//
//    public double computeCost(Map<String, Object> message, Map<String, Object> solution) {
//        int car_id = Integer.parseInt(solution.get("car_id").toString());
//        int start_id = Integer.parseInt(solution.get("need_owner").toString());
//        int end_id = Integer.parseInt(message.get("destination").toString());
//        double weight = Double.parseDouble(message.get("goods_weight").toString());
//        double volume = Double.parseDouble(message.get("goods_volume").toString());
//        double integration = Double.parseDouble(message.get("integration_distance").toString());
//        int car_position = carMapper.getCarPosition(car_id);
//        double load_m = Double.parseDouble(car_messageMapper.getCarMessage(car_id).get("load_m").toString());
//        double load_v = Double.parseDouble(car_messageMapper.getCarMessage(car_id).get("load_v").toString());
//        double percent_m,percent_v,percent;
//        if (weight/load_m>1)
//            percent_m=1;
//        else
//            percent_m=weight/load_m;
//        if (volume/load_v>1)
//            percent_v=1;
//        else
//            percent_v=volume/load_v;
//        percent=Math.max(percent_m,percent_v);
//        return 1.6*distanceMapper.getDuration(car_position,start_id)+1.25*(1-percent)*distanceMapper.getDistance(start_id,end_id)-5*Math.sqrt(distanceMapper.getDuration(start_id,end_id))+integration;
//    }

//    public Map<String, Object> SA(List<Map<String, Object>> solutions, int best_solution_id, double min_cost,Map<String,Object> row,double t,double t_low,int trs){
//        for(;t>0;t=t-t_low){
//            int jump = random.nextInt((int)Math.ceil(t/trs))+1;
//            int solution_id;
//            if(best_solution_id == 0)
//                solution_id = best_solution_id + jump;
//            else {
//                if (best_solution_id == solutions.size() - 1)
//                solution_id = best_solution_id - jump;
//                else {
//                    int left_or_right = random.nextInt(2);
//                    if (left_or_right == 0)
//                        solution_id = Math.max(best_solution_id - jump, 0);
//                    else
//                        solution_id = Math.min(best_solution_id + jump, solutions.size() - 1);
//                }
//            }
//            double cost = computeCost(row,solutions.get(solution_id));
//            if(cost<min_cost){
//                solutions.remove(best_solution_id);
//                if(solution_id<=best_solution_id) {
//                    min_cost = cost;
//                    best_solution_id = solution_id;
//                }
//                else {
//                    min_cost = cost;
//                    best_solution_id = solution_id-1;
//                }
//            }
//            else {
//                if(random.nextDouble() < Math.exp((min_cost-cost)/t)) {
//                    min_cost = cost;
//                    best_solution_id = solution_id;
//                }
//                else {
//                    solutions.remove(solution_id);
//                    if(solution_id<=best_solution_id) {
//                        best_solution_id = best_solution_id-1;
//                    }
//                }
//            }
//        }
//        Map<String,Object> result = new HashMap<>();
//        result.put("need_owner",solutions.get(best_solution_id).get("need_owner"));
//        result.put("car_id",solutions.get(best_solution_id).get("car_id"));
//        result.put("min_cost",min_cost);
//        return result;
//    }

//    public List<Map<String, Object>> queryMessages(){
//        List<Map<String, Object>> messages = messageMapper.queryMessages();
//        List<Map<String, Object>> MESSAGES = new ArrayList<>();
//        for(Map<String, Object> row : messages){
//            int message_id = Integer.parseInt(row.get("message_id").toString());
//            int need_goods_type = Integer.parseInt(row.get("need_goods_type").toString());
//            int destination = Integer.parseInt(row.get("destination").toString());
//            List<Map<String, Object>> matches = ownersMapper.getOwnerMatches(message_id);
//            for(Map<String,Object> row2 : matches){
//                int need_owner = Integer.parseInt(row2.get("owner_id").toString());
//                int car_id = Integer.parseInt(row2.get("car_id").toString());
//                int refuse_or_not = Integer.parseInt(row2.get("refuse_or_not").toString());
//                String goodsType = goodsMapper.getGoods_type(need_goods_type);
//                Map<String,Object> MESSAGE = new HashMap<>();
//                MESSAGE.put("messageId",message_id);
//                MESSAGE.put("goodsType",goodsType);
//                MESSAGE.put("carId",car_id);
//                MESSAGE.put("startId",need_owner);
//                MESSAGE.put("endId",destination);
//                MESSAGE.put("refuseOrNot",refuse_or_not);
//                MESSAGES.add(MESSAGE);
//            }
//        }
//        return MESSAGES;
//    }
}

